package com.hy.ai.config;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.*;
import com.hy.ai.entity.po.ChatRedisMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.memory.ChatMemory;
import com.hy.ai.entity.po.ChatMessage;
import com.hy.ai.mapper.ChatMessageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Type;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class MySqlChatMemory implements ChatMemory {

    @Autowired
    private  ChatMessageMapper chatMessageMapper;
    @Autowired
    private  StringRedisTemplate stringRedisTemplate;
    Gson gson = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (src, typeOfSrc, context) -> {
                return new JsonPrimitive(src.toString()); // 或使用 DateTimeFormatter.ISO_LOCAL_DATE_TIME
            })
            .registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json, typeOfT, context) -> LocalDateTime.parse(json.getAsString()))
            .create();

    @Transactional
    @Override
    public void add(String conversationId, List<Message> messages) {
        for (Message message : messages) {
            //保存到MySQL
            ChatMessage entity = new ChatMessage();
            entity.setConversationId(conversationId);
            entity.setRole(message.getMessageType().name().toLowerCase()); // "user" or "assistant"
            entity.setContent(message.getText());
            entity.setCreatedAt(LocalDateTime.now());
            chatMessageMapper.insert(entity);

            //同步到redis
            ChatRedisMessage redisMessage = new ChatRedisMessage();
            redisMessage.setRole(entity.getRole());
            redisMessage.setContent(entity.getContent());
            redisMessage.setCreatedAt(entity.getCreatedAt());
            // 推入 Redis List（右边）
            stringRedisTemplate.opsForList().rightPush("ID:1:" + conversationId, gson.toJson(redisMessage));

            // 设置过期时间为2小时
            stringRedisTemplate.expire("ID:1:" + conversationId, Duration.ofHours(2));

        }
    }

    @Override
    public List<Message> get(String conversationId, int lastN) {
        String key="ID:1:"+conversationId;
        //先从redis获取
        Long size = stringRedisTemplate.opsForList().size(key);
        List<String> jsonList = stringRedisTemplate.opsForList().range(key, Math.max(0, size - lastN), size - 1);
        if(!jsonList.isEmpty()){
            //缓存命中
            return jsonList.stream().map(json -> {
                try {
                    ChatRedisMessage m = gson.fromJson(json, ChatRedisMessage.class);
                    return "user".equals(m.getRole()) ?
                            new UserMessage(m.getContent()) :
                            new AssistantMessage(m.getContent());
                } catch (Exception e) {
                    System.err.println("Redis反序列化失败: " + json);
                    return null;
                }
            }).filter(Objects::nonNull).collect(Collectors.toList());

        }
        //缓存未命中
        System.out.println("缓存未命中");
        LambdaQueryWrapper<ChatMessage> query = Wrappers.lambdaQuery(ChatMessage.class)
                .eq(ChatMessage::getConversationId, conversationId)
                .orderByDesc(ChatMessage::getCreatedAt)
                .last("LIMIT " + lastN);

        List<ChatMessage> messages = chatMessageMapper.selectList(query);

        Collections.reverse(messages); // 按时间升序排列（先旧后新）

        for (ChatMessage msg:messages){
            ChatRedisMessage redisMessage = new ChatRedisMessage();
            redisMessage.setRole(msg.getRole());
            redisMessage.setContent(msg.getContent());
            redisMessage.setCreatedAt(msg.getCreatedAt());
            // 推入 Redis List（右边）
            stringRedisTemplate.opsForList().rightPush(key, gson.toJson(redisMessage));

            // 设置过期时间为2小时
            stringRedisTemplate.expire(key, Duration.ofHours(2));
        }
        return messages.stream().map(chatMessage -> {
            String role = chatMessage.getRole();
            String content = chatMessage.getContent();
            if ("user".equalsIgnoreCase(role)) {
                return new UserMessage(content);
            } else if ("assistant".equalsIgnoreCase(role)) {
                return new AssistantMessage(content);
            } else {
                // 默认处理未知角色为 UserMessage（或可抛出异常）
                return new UserMessage(content);
            }
        }).collect(Collectors.toList());
    }

    @Override
    public void clear(String conversationId) {
        String key="ID:1:"+conversationId;
        // 删除 Redis 缓存
        stringRedisTemplate.delete(key);
        // 删除 MySQL 数据
        chatMessageMapper.delete(Wrappers.lambdaQuery(ChatMessage.class)
                .eq(ChatMessage::getConversationId, conversationId));
    }
}
